package streamforce.crypto.cloud.subscriber;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import streamforce.Stat;
import streamforce.crypto.KPAbe;
import streamforce.crypto.cloud.EPCloud;
import streamforce.crypto.cloud.EPCloudServer;
import streamforce.crypto.cloud.TimeTuple;
import streamforce.crypto.cloud.Tuple;
import streamforce.crypto.event.Ciphertext;
import streamforce.crypto.event.TransformedCTEventAll;
import streamforce.crypto.policies.Policy;

//for query: select price from StockEvent(cond)
//assuming that the cryptohandler has been initialized
public class CloudSelectAll extends Policy{
	final Log log = LogFactory.getLog(CloudSelectAll.class);
	
	int userId;//the same as userId
	Stat stat, statTuple; 
	
	public CloudSelectAll(int pi, KPAbe ch){
		super(ch);
		this.userId = pi;
		this.stat = new Stat("nTransformed"); 
		this.statTuple = new Stat("nTuples"); 
	}
	
	public int getUserId(){
		return this.userId;
	}
	
	public void update(int timestamp, int hour, int stockId,
			Ciphertext ctPrice, Ciphertext ctVolume) {				
		if (ctPrice != null && ctVolume != null) {			
				
			byte[] ciphertextPrice = ctPrice.getCipher();
			byte[] ciphertextVolume = ctVolume.getCipher();
			long start = System.currentTimeMillis();
			byte[][] originals, transforms; 
			
				byte[] tctPrice = this.cryptoHandler.transform_simple(
						ciphertextPrice, stockId, this.userId);
				byte[] tctVolume = this.cryptoHandler.transform_simple(
						ciphertextVolume, stockId, this.userId);								
				byte[] originalPrice = this.cryptoHandler
						.extractOriginalCipher(stockId, ciphertextPrice);
				byte[] originalVolume = this.cryptoHandler
						.extractOriginalCipher(stockId, ciphertextVolume);
				 originals = new byte[2][originalPrice.length];
				originals[0] = originalPrice;
				originals[1] = originalVolume;
				 transforms = new byte[2][tctPrice.length];
				transforms[0] = tctPrice;
				transforms[1] = tctVolume;
			
				// then construct and send another event
				TransformedCTEventAll cte = new TransformedCTEventAll(
						this.userId, timestamp, hour, stockId, originals, transforms,
						TransformedCTEventAll.SELECT_ALL);

				long end = System.currentTimeMillis();
				log.info("simple transform time = " + (end - start));
				
				TimeTuple tt = EPCloudServer.tupleTime.get(new Tuple(stockId, timestamp)); 
			if (tt != null) {
				if (tt.getCount() == 0)
					this.statTuple.update();
				tt.increaseCount();
				if (EPCloudServer.QUEUE_DUMP)
					log.info(String.format("queue (%d,%d): %d", stockId,
							timestamp,
							(System.currentTimeMillis() - tt.getStart())));
			}
				this.stat.update();
				EPCloud.getEPServiceProvider().getEPRuntime().sendEvent(cte);
								
			//}
		}
		
	}
}
